<?php
namespace User\Controller;
use Think\Controller;

/**
 * @Author: Martin Zhou
 * @Version: 1.0.1
 * @Copyright Tencent Security Response Center (TSRC)
 * @Project  https://security.tencent.com/index.php/xsrc
*/

class RegController extends Controller{
	
    public function index()
    {
		$tmodel= M('setting');
		$title = $tmodel->where('id=1')->select();
		$this->assign('title', $title);
		$this->display();
    }
  
    /**
     * 用户注册
     */
    public function add(){
        if (!IS_POST) {
            $this->display();
        }
		
        if (IS_POST) {
            $setting = M('setting')->where(array('name'=>'site_register_setting'))->find();
            if($setting['value'] != 1){
                $result = ['code'=> 400, 'msg' => '尚未开启用户注册'];
                $this->ajaxReturn($result,'JSON');
            }
            $rawData = file_get_contents("php://input");
            // 解码 JSON 数据
            $data = json_decode($rawData, true); // 第二个参数为 true 返回数组，若为 false 则返回对象
            $password =  $data['password'];
            $code = $data['verify'];
            $email =  $data['email']; 
            $username =  $data['username']; 
            $repassword =  $data['rePassword']; 
             
			$data['salt'] = "";
			$data['pid'] = "";
			$chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
			$pchars = '0123456789';
			for($num=0;$num<8;$num++){
				$RandNum = rand(0,strlen($chars)-1);  
				$data['salt'] .= $chars[$RandNum]; 
			}
			
			for($num=0;$num<32;$num++){
				$RandNum = rand(0,strlen($pchars)-1);  
				$data['pid'] .= $pchars[$RandNum]; 
			}         	 
			
			if(strlen($data['username']) > 20){ 
			    //$this->error("用户名长度超过20个字符"); 
			    $result = ['code'=> 400, 'msg' => '用户名长度超过20个字符'];
			    $this->ajaxReturn($result,'JSON'); 
			}
			if($data['password'] != $repassword){
			    //$this->error("两次密码不一致");
			    $result = ['code'=> 400, 'msg' => '两次密码不一致'];
			    $this->ajaxReturn($result,'JSON');
			} 
			
			if(!($this->check_verify($code,'register'))){
			    //$this->error('验证码错误');
			    $result = ['code'=> 400, 'msg' => '验证码错误'];
			    $this->ajaxReturn($result,'JSON');
			}
			
			//if(strlen($data['password']) < 8){ $this->error("为了保证帐户安全，请输入大于八位数的密码!");} 
			$result = $this->isValidPassword($data['password'],$data);
		
			if($result['code'] == 400){
			    $this->ajaxReturn($result,'JSON'); 
			}
			
		

			$data['password'] = md5(md5(md5($data['salt']).md5($data['password'])."SR")."CMS"); //“SR”和“CMS”可修改
			$data['create_at']=time();
			$model = M("Member");
		
			if ($model->where(array('username'=>$data['username']))->find()){
				 //$this->error('用户名重复');
				 $result = ['code'=> 400, 'msg' => '用户名重复'];
				 $this->ajaxReturn($result,'JSON'); 
			}
			if ($model->where(array('email'=>$data['email']))->find()){
				 //$this->error('邮箱重复');
				 $result = ['code'=> 400, 'msg' => '邮箱重复'];
				 $this->ajaxReturn($result,'JSON'); 
			}
			
			if ($model->field('username,email,pid,salt,password,create_at')->data($data)->add()) {
	
				$user = $model->where(array('username'=>$data['username']))->find();		

				$date =array(
					'id' => $user['id'],
					'update_at' => time(),
					'login_ip' => get_client_ip(),
				);
        
				if($model->save($date)){
					//$this->redirect('index/index');
				    $result = ['code'=> 200, 'msg' => '注册成功', url => U('Index/index')];
					$this->ajaxReturn($result,'JSON'); 
				}	
		
            } else {
                //$this->error("注册失败");
                $result = ['code'=> 400, 'msg' => '注册失败'];
                $this->ajaxReturn($result,'JSON'); 
            }
        }
    }
	
	//验证码
    public function verify(){
		ob_clean();
        $Verify = new \Think\Verify();
        $Verify->codeSet = '123456789abcdefghijklmnopqrst';
        $Verify->fontSize = 20;
        $Verify->length = 4;
        $Verify->entry();
    } 
    /**
     * 密码验证函数
     * @param unknown $password
     * @param unknown $data
     * @return boolean
     */
    public function isValidPassword($password,$data) {   
        // 检查密码长度是否大于8位
        if (strlen($password) <= 8) {
            return ["code" => 400, "msg" => "密码长度必须大于8位"];
        } 
        // 用于存储每种字符类型的存在性
        $hasUpper = preg_match('/[A-Z]/', $password);
        $hasLower = preg_match('/[a-z]/', $password);
        $hasDigit = preg_match('/\d/', $password);
        $hasSpecial = preg_match('/[!@#$%^&*()_+\-=\[\]{};":\\|,.<>\/?]+/', $password);
        
        // 计算存在的字符类型数量
        $typesCount = $hasUpper + $hasLower + $hasDigit + $hasSpecial;
        
        // 检查是否至少包含三种类型
        if ($typesCount < 3) {
            return  ["code" => 400, "msg" =>"密码必须包含三种以上字符类型（大写字母、小写字母、数字、特殊字符）"];
        }
        
        // 检查是否有连续数字
        if (preg_match('/(\d)\1{2,}/', $password)) {
            return  ["code" => 400, "msg" =>"密码不能包含连续的数字"];
        }
        
        // 检查是否有连续字母
        if (preg_match('/([a-zA-Z])\1{2,}/', $password)) {
            return  ["code" => 400, "msg" =>"密码不能包含连续的字母"];
        }
        
        // 检查是否有三个或更多相同字符
        if (preg_match('/(.)\1{2,}/', $password)) {
            return  ["code" => 400, "msg" =>"密码不能包含三个或更多相同字符"];
        }
        
        // 检查密码中是否包含 "newland"（不区分大小写）
        if (preg_match('/newland/i', $password)) {
            return  ["code" => 400, "msg" =>"密码不能包含 'newland'（不区分大小写）"];
        }
        // 检查密码中是否包含 "newland"（不区分大小写）
        if (preg_match('/postar/i', $password)) {
            return  ["code" => 400, "msg" =>"密码不能包含 'postar'（不区分大小写）"];
        }
        
        // 检查密码中是否包含 "newland"（不区分大小写）
        if (preg_match('/postar/i', $password)) {
            return  ["code" => 400, "msg" =>"密码不能包含 'postar'（不区分大小写）"];
        }
        //密码不能和用户名  或  邮箱一致
        if($password == $data['email'] || $password == $data['username']){ 
            return  ["code" => 400, "msg" =>"密码不能和用户名或邮箱一致"];
        } 
        $tmodel= M('weekpassword');
        $exist = $tmodel->where(array('password'=>$password))->find();
        if($exist){
            return  ["code" => 400, "msg" =>"密码不能存在于安全联盟建立的弱密码字典中"];
        } 
        
       return  ["code" => 200, "msg" =>"密码有效"];
    }
    protected function check_verify($code, $tab){
        $verify = new \Think\Verify();
        return $verify->check($code, $tab);
    }
}
